package com.example.start.Interceptor;

import com.example.dmcommom.*;
import com.example.dmdomain.UserRepository;
import com.example.dmdomain.entity.User;
import com.example.dmservice.auth.AuthService;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

@Component
public class AuthenticationInterceptor implements HandlerInterceptor {

	@Resource
	private UserRepository userService;

	@Resource
	private AuthService authService;

	@Resource
	private RedisUtils redisUtils;

	@Override
	public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object object) {
		if ("OPTIONS".equalsIgnoreCase(httpServletRequest.getMethod())) {
			return true;
		}
		// 如果不是映射到方法直接通过
		if (!(object instanceof HandlerMethod)) {
			return true;
		}

		Method method = ((HandlerMethod) object).getMethod();

		//检查是否有NoAuthInterception注释，有则跳过认证
		if (method.isAnnotationPresent(NoAuthInterception.class)) {
			NoAuthInterception noAuthInterception = method.getAnnotation(NoAuthInterception.class);
			if (noAuthInterception.required()) {
				return true;
			}
		}
		//检查是否有PrivateMethod注释，有则验证IP是否和本机一致
		if (method.isAnnotationPresent(PrivateMethod.class)) {
			PrivateMethod privateMethod = method.getAnnotation(PrivateMethod.class);
			String ipAddress = IPUtils.getRealIP(httpServletRequest);
			if (privateMethod.required() && IPUtils.getLocalIp().equals(ipAddress)) {
				return true;
			}
		}

		// 从 http 请求头中取出 token
		String userId = httpServletRequest.getHeader("authorization");
		if (StringUtils.isEmpty(userId)) {
			throw new AuthException("未找到指定用户");
		}

		User user = userService.findUsersByUserID(userId);
		if (user == null) {
			throw new AuthException("账户不存在或未授权!");
		}

		boolean result = authService.checkPermission(user);
		if (!result) {
			throw new AuthException("账户不存在或未授权!");
		}
		return result;
	}

	@Override
	public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
	}

	@Override
	public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
	}
}